<?php

class Damages_ErrorController extends Zend_Controller_Action {

  const BACKEND_CONTROLLER_NAME = 'Backend';

  public function errorAction() {
    $errors = $this->_getParam('error_handler');
    $controllerName = $this->_request->getParam('controller');
    if ($controllerName == self::BACKEND_CONTROLLER_NAME) {
      $this->backendError($errors);
      return;
    } else {
      $this->frontendError($errors);
      return;
    }
  }

  private function backendError($errors) {
    $this->jsonData();
    $response = new stdClass();
    if ($errors->exception instanceof Damages_Exception_App || $this->getInvokeArg('displayExceptions') == true) {
      $exception = $errors->exception;
    } else {
      $exception = new Damages_Exception_App(100, array($errors->exception->getMessage()));
    }
    if ($errors->exception instanceof Damages_Exception_App){
      $response->exception = $exception->getUserMessage();
      $response->callback = $exception->getCallback();
    }
    else
      $response->exception = $exception->getMessage();
    $response->exceptionCode = $exception->getCode();
    if ((bool) Zend_Registry::get('appConfig')->resources->frontController->params->displayExceptionsDetails) {
      $response->exceptionDetails = new stdClass();
      $response->exceptionDetails->class = get_class($exception);
      $response->exceptionDetails->code = $exception->getCode();
      $response->exceptionDetails->file = $exception->getFile();
      $response->exceptionDetails->line = $exception->getLine();
      $response->exceptionDetails->message = $exception->getMessage();
      $response->exceptionDetails->previous = $exception->getPrevious();
      $response->exceptionDetails->trace = $exception->getTraceAsString();
      if ($errors->exception instanceof Damages_Exception_App) {
        $response->exceptionDetails->type = $exception->getType();
        $response->exceptionDetails->userMessage = $exception->getUserMessage();
      }
    }
    $this->view->response = $response;
  }

  private function frontendError($errors) {
    $this->_helper->layout->disableLayout();
    if (!$errors || !$errors instanceof ArrayObject) {
      $this->view->message = 'You have reached the error page';
      return;
    }

    switch ($errors->type) {
      case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
      case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
      case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
        // 404 error -- controller or action not found
        $this->getResponse()->setHttpResponseCode(404);
        $priority = Zend_Log::NOTICE;
        $this->view->message = 'Page not found';
        break;
      default:
        // application error
        $this->getResponse()->setHttpResponseCode(500);
        $priority = Zend_Log::CRIT;
        $this->view->message = 'Application error';
        break;
    }

    // Log exception, if logger available
    if ($log = $this->getLog()) {
      $log->log($this->view->message, $priority, $errors->exception);
      $log->log('Request Parameters', $priority, $errors->request->getParams());
    }

    // conditionally display exceptions
    if ($this->getInvokeArg('displayExceptions') == true) {
      $this->view->exception = $errors->exception;
    }
    $this->view->request = $errors->request;
  }

  private function jsonData() {
    $this->_helper->layout->disableLayout();
    $action = $this->getRequest()->getActionName();
    //$this->_helper->viewRenderer->setNoRender(true);
    $this->_helper->contextSwitch()
            ->addActionContext($action, 'json')
            ->setAutoJsonSerialization(true)
            ->initContext('json');
    $this->getRequest()->setParam('format', 'json');
  }

  public function getLog() {
    $bootstrap = $this->getInvokeArg('bootstrap');
    if (!$bootstrap->hasResource('Log')) {
      return false;
    }
    $log = $bootstrap->getResource('Log');
    return $log;
  }

}

